{ *********************************************************************************** }
{ *                              CryptoLib Library                                  * }
{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
{ *                 Github Repository <https://github.com/Xor-el>                   * }

{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }

{ *                              Acknowledgements:                                  * }
{ *                                                                                 * }
{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
{ *                           development of this library                           * }

{ * ******************************************************************************* * }

(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)

unit SpeckTestVectors;

interface

{$IFDEF FPC}
{$MODE DELPHI}
{$ENDIF FPC}

uses
  ClpCryptoLibTypes;

type
  /// <summary>
  /// Speck tester
  /// </summary>
  /// <remarks>
  /// test vectors were gotten from <see href="https://eprint.iacr.org/2013/404.pdf" />
  /// , <br /><see href="https://nsacyber.github.io/simon-speck/implementations/ImplementationGuide1.1.pdf" />
  /// and
  /// https://github.com/weidai11/cryptopp/blob/master/TestVectors/speck.txt <br />
  /// (do note that the tests vector in the first link are given in big
  /// endian order) <br />and were swapped to little endian here
  /// </remarks>
  TSpeckTestVectors = class sealed(TObject)

  public
    class var

      FSpeck32BlockCipherVectorKeys, FSpeck32BlockCipherVectorInputs,
      FSpeck32BlockCipherVectorOutputs,

      FSpeck48BlockCipherVectorKeys, FSpeck48BlockCipherVectorInputs,
      FSpeck48BlockCipherVectorOutputs,

      FSpeck64BlockCipherVectorKeys, FSpeck64BlockCipherVectorInputs,
      FSpeck64BlockCipherVectorOutputs,

      FSpeck96BlockCipherVectorKeys, FSpeck96BlockCipherVectorInputs,
      FSpeck96BlockCipherVectorOutputs,

      FSpeck128BlockCipherVectorKeys, FSpeck128BlockCipherVectorInputs,
      FSpeck128BlockCipherVectorOutputs,

      FSpeck32LegacyBlockCipherVectorKeys,
      FSpeck32LegacyBlockCipherVectorInputs,
      FSpeck32LegacyBlockCipherVectorOutputs,

      FSpeck48LegacyBlockCipherVectorKeys,
      FSpeck48LegacyBlockCipherVectorInputs,
      FSpeck48LegacyBlockCipherVectorOutputs,

      FSpeck64LegacyBlockCipherVectorKeys,
      FSpeck64LegacyBlockCipherVectorInputs,
      FSpeck64LegacyBlockCipherVectorOutputs,

      FSpeck96LegacyBlockCipherVectorKeys,
      FSpeck96LegacyBlockCipherVectorInputs,
      FSpeck96LegacyBlockCipherVectorOutputs,

      FSpeck128LegacyBlockCipherVectorKeys,
      FSpeck128LegacyBlockCipherVectorInputs,
      FSpeck128LegacyBlockCipherVectorOutputs,

      FCryptoPPVectorKeys_SPECK64_ECB, FCryptoPPVectorInputs_SPECK64_ECB,
      FCryptoPPVectorOutputs_SPECK64_ECB,

      FCryptoPPVectorKeys_SPECK128_ECB, FCryptoPPVectorInputs_SPECK128_ECB,
      FCryptoPPVectorOutputs_SPECK128_ECB,

      FCryptoPPVectorKeys_SPECK64_CBC, FCryptoPPVectorIVs_SPECK64_CBC,
      FCryptoPPVectorInputs_SPECK64_CBC, FCryptoPPVectorOutputs_SPECK64_CBC,

      FCryptoPPVectorKeys_SPECK128_CBC, FCryptoPPVectorIVs_SPECK128_CBC,
      FCryptoPPVectorInputs_SPECK128_CBC, FCryptoPPVectorOutputs_SPECK128_CBC,

      FCryptoPPVectorKeys_SPECK64_CTR, FCryptoPPVectorIVs_SPECK64_CTR,
      FCryptoPPVectorInputs_SPECK64_CTR, FCryptoPPVectorOutputs_SPECK64_CTR,

      FCryptoPPVectorKeys_SPECK128_CTR, FCryptoPPVectorIVs_SPECK128_CTR,
      FCryptoPPVectorInputs_SPECK128_CTR, FCryptoPPVectorOutputs_SPECK128_CTR

      : TCryptoLibStringArray;

    class constructor SpeckTestVectors();

  end;

implementation

{ TSpeckTestVectors }

class constructor TSpeckTestVectors.SpeckTestVectors;
begin

  FSpeck32BlockCipherVectorKeys := TCryptoLibStringArray.Create
    ('0001080910111819');

  FSpeck32BlockCipherVectorInputs := TCryptoLibStringArray.Create('4C697465');

  FSpeck32BlockCipherVectorOutputs := TCryptoLibStringArray.Create('F24268A8');

  FSpeck48BlockCipherVectorKeys := TCryptoLibStringArray.Create
    ('00010208090A101112', '00010208090A101112', '00010208090A10111218191A');

  FSpeck48BlockCipherVectorInputs := TCryptoLibStringArray.Create
    ('72616C6C7920', '72616C6C7920', '74686973206D');

  FSpeck48BlockCipherVectorOutputs := TCryptoLibStringArray.Create
    ('DC5A38A549C0', 'DC5A38A549C0', '5D44B6105E73');

  FSpeck64BlockCipherVectorKeys := TCryptoLibStringArray.Create
    ('0001020308090A0B10111213', '0001020308090A0B1011121318191A1B');

  FSpeck64BlockCipherVectorInputs := TCryptoLibStringArray.Create
    ('65616E7320466174', '2D4375747465723B');

  FSpeck64BlockCipherVectorOutputs := TCryptoLibStringArray.Create
    ('6C947541EC52799F', '8B024E4548A56F8C');

  FSpeck96BlockCipherVectorKeys := TCryptoLibStringArray.Create
    ('00010203040508090A0B0C0D', '00010203040508090A0B0C0D101112131415');

  FSpeck96BlockCipherVectorInputs := TCryptoLibStringArray.Create
    ('2075736167652C20686F7765', '7665722C20696E2074696D65');

  FSpeck96BlockCipherVectorOutputs := TCryptoLibStringArray.Create
    ('AA798FDEBD627871AB094D9E', 'E62E2540E47A8A227210F32B');

  FSpeck128BlockCipherVectorKeys := TCryptoLibStringArray.Create
    ('000102030405060708090A0B0C0D0E0F',
    '000102030405060708090A0B0C0D0E0F1011121314151617',
    '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F');

  FSpeck128BlockCipherVectorInputs := TCryptoLibStringArray.Create
    ('206D616465206974206571756976616C', '656E7420746F20436869656620486172',
    '706F6F6E65722E20496E2074686F7365');

  FSpeck128BlockCipherVectorOutputs := TCryptoLibStringArray.Create
    ('180D575CDFFE60786532787951985DA6', '86183CE05D18BCF9665513133ACFE41B',
    '438F189C8DB4EE4E3EF5C00504010941');

  // speck legacy test vectors

  FSpeck32LegacyBlockCipherVectorKeys := TCryptoLibStringArray.Create
    ('1918111009080100');

  FSpeck32LegacyBlockCipherVectorInputs := TCryptoLibStringArray.Create
    ('6574694C');

  FSpeck32LegacyBlockCipherVectorOutputs := TCryptoLibStringArray.Create
    ('A86842F2');

  FSpeck48LegacyBlockCipherVectorKeys := TCryptoLibStringArray.Create
    ('1211100A0908020100', '1A19181211100A0908020100');

  FSpeck48LegacyBlockCipherVectorInputs := TCryptoLibStringArray.Create
    ('20796C6C6172', '6D2073696874');

  FSpeck48LegacyBlockCipherVectorOutputs := TCryptoLibStringArray.Create
    ('C049A5385ADC', '735E10B6445D');

  FSpeck64LegacyBlockCipherVectorKeys := TCryptoLibStringArray.Create
    ('131211100B0A090803020100', '1B1A1918131211100B0A090803020100');

  FSpeck64LegacyBlockCipherVectorInputs := TCryptoLibStringArray.Create
    ('74614620736E6165', '3B7265747475432D');

  FSpeck64LegacyBlockCipherVectorOutputs := TCryptoLibStringArray.Create
    ('9F7952EC4175946C', '8C6FA548454E028B');

  FSpeck96LegacyBlockCipherVectorKeys := TCryptoLibStringArray.Create
    ('0D0C0B0A0908050403020100', '1514131211100D0C0B0A0908050403020100');

  FSpeck96LegacyBlockCipherVectorInputs := TCryptoLibStringArray.Create
    ('65776F68202C656761737520', '656D6974206E69202C726576');

  FSpeck96LegacyBlockCipherVectorOutputs := TCryptoLibStringArray.Create
    ('9E4D09AB717862BDDE8F79AA', '2BF31072228A7AE440252EE6');

  FSpeck128LegacyBlockCipherVectorKeys := TCryptoLibStringArray.Create
    ('0F0E0D0C0B0A09080706050403020100',
    '17161514131211100F0E0D0C0B0A09080706050403020100',
    '1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100');

  FSpeck128LegacyBlockCipherVectorInputs := TCryptoLibStringArray.Create
    ('6C617669757165207469206564616D20', '726148206665696843206F7420746E65',
    '65736F6874206E49202E72656E6F6F70');

  FSpeck128LegacyBlockCipherVectorOutputs := TCryptoLibStringArray.Create
    ('A65D9851797832657860FEDF5C570D18', '1BE4CF3A13135566F9BC185DE03C1886',
    '4109010405C0F53E4EEEB48D9C188F43');

  // https://github.com/weidai11/cryptopp/blob/master/TestVectors/speck.txt

  // ====================================================================================== //

  FCryptoPPVectorKeys_SPECK64_ECB := TCryptoLibStringArray.Create
    ('F64F824BDA9DA2D0D446ABE3', '64B76FA61CE980AB2F71098D75D66E5F');
  FCryptoPPVectorInputs_SPECK64_ECB := TCryptoLibStringArray.Create
    ('48731C8BFE3260D4', '1589A8BBFF4C7A85');
  FCryptoPPVectorOutputs_SPECK64_ECB := TCryptoLibStringArray.Create
    ('55CABA8DE9F967C8', '2F1D122370946BDA');

  // ====================================================================================== //

  FCryptoPPVectorKeys_SPECK128_ECB := TCryptoLibStringArray.Create
    ('75289E33D18BDFC9C689B29A43CBF3F2',
    'C289F537364FF63CB37FD75FEFB7C64D9D0997CD230B0BA2',
    '3FAD1C9A616C155D42A077C2458E6BBA12C340F1475EA1F1624F8636FFB14ECC');
  FCryptoPPVectorInputs_SPECK128_ECB := TCryptoLibStringArray.Create
    ('51C16CD9AFAB4F1D326658F89C06C940', '0FF691D4E981FEFFC226BB85C2793B45',
    '83A3C8AC4655B7B09FD2E6372F67D80B');
  FCryptoPPVectorOutputs_SPECK128_ECB := TCryptoLibStringArray.Create
    ('C003C0497684789B3A6CCBE8E7F98D9E', 'A757BDA6BAFD5356AE0693B89E4124F9',
    'C1666B5CEFC7A834AA8E17151325D89C');

  // ====================================================================================== //

  FCryptoPPVectorKeys_SPECK64_CBC := TCryptoLibStringArray.Create
    ('87A6829C1FDAAB90AC8AFC52', 'CA4345F53BE6D8F371D91C334FC0838B');

  FCryptoPPVectorIVs_SPECK64_CBC := TCryptoLibStringArray.Create
    ('869AF558D633F02D', '51A3A8DE472EF740');

  FCryptoPPVectorInputs_SPECK64_CBC := TCryptoLibStringArray.Create
    ('2DE1856588CAC5A3225A1048A6C9C98E7B6E1E80DF1DD431AC075133555F1091B075AAE0D05C057249D0032D78DE2CD74F1BB05AE8C38347088C1207D3EF53890F35F0FA99BBDB10F17DB0F8E7AFD03E40DD31E2B4330CAFE1C329930096CEEA',
    '8A46B92E16B50EA93080F6801A0F77D7B1C7A11E8F212D036EDC6AB5E30ADE3B6A980C36FD40A62EB868F42B8CFB5907EBDA51F1C9D394DB691A326FA0DB093B632FEE98C106207AEFC6E26DC14724AD7684E2D54F7C3417A1BF438224B23FF1');

  FCryptoPPVectorOutputs_SPECK64_CBC := TCryptoLibStringArray.Create
    ('570D66C5A24534BF916C25B7F1093A0555C54857A11FDBCE549E3CFA0E65307F46B3796025925E55DD53D4419E5651A6B4D615DCB34EF4AADF7CA9AE4B0B266BCB2DBB78F933028E655F9F00820A8B32C27CB7481C071C012B54DCFB1FBFDB62',
    'F2475EFA5C2F3BB9D4D16DFF5E3A3D16679C265660F6ABD2C4FC73B84806127ADDFAACC45E968770C747E2D6D66CF1AA37C96637DED14E439DA5F99778F4BA226592DFEDFE7EAB84D9B3665F71A6F9CC6E3AD6C8CCA1DB91D0F4F8BC572ED873');

  // ====================================================================================== //

  FCryptoPPVectorKeys_SPECK128_CBC := TCryptoLibStringArray.Create
    ('84B6C2745A7515168E794BC312949733',
    '52EB87E80BC7BE50A0F2C823BFC1D1478540010A1E61BA1E',
    '4FFE6ED614F3662199AB5B77C01FFEFFF6F2A2928486F2CBD0AA0555E28837E9');

  FCryptoPPVectorIVs_SPECK128_CBC := TCryptoLibStringArray.Create
    ('89B996EC3A2030EEAB18E777A4A826F4', '817111309CF0E5FDD3D29A87F24A3D42',
    '2A6421928921E1A364798D330D22E4C3');

  FCryptoPPVectorInputs_SPECK128_CBC := TCryptoLibStringArray.Create
    ('E99CEF37FA72BB342275090D36460E599982535234C52780FA11AE65F36208B82D9C439183DBF93CB1EC5E7'
    + 'B14EA3707C6C5A4C12F9942C43C24D0FE1BB17BC473137E3E55B7687113A71DDFF47623B29B5431656976E8BE845FA2676F4B5073D980BE0BC45216299B8D8A2026E21B6C4737F3601196307D82F986D0D44808951172A160B4EE2D'
    + 'CA04C4EAE7D5BB53BA0929C990AA706495BDEF15DD989C1460CB821FEDB14EFBEB6CEF223B4BA00F6FCB775B79EBD4F2FCDC570057045B9956',
    'B3DACAA4EE7C1AE96BF563F9EEAE8C32A47A2CC10F9D1F06CFDC1BC5AC57BF425F4D2816A4517035DBEB9A43E6EE7BBF592B861BB04077AD784B19'
    + '049B6E25D8E85182053B0C89695B3F49CA874CA37F263E004862FFC178B82E7844B13AE98E3E7E4DE517BF00F89316C54CECA154A9A618C4CECA7D0F5423A459335B6758AE2D0134526791EEC3A1730B055C3D6A8A96422A37'
    + 'DF32F910365B319FED76591EA32865920A4357BFF6B3DED6DEB9A453F8A4FFE66AE621159F40DE5170F94EAC',
    '05DE17F97F9DC2DF3BA5858D161B21255C539BC715A55D8CD09BAE727920CB5744CDA1B7C962B13B4263F0D67B65ACFA84D6CBEB95B187032F5887D4DB0A'
    + '509E14FF4373546BE2B4071B78387EB6922591E2F276E8FABE4E3BCC444D036EC400C9980F45D09F79D5DA9FF01A9B1950874013BC855BAB6F922030DA96FB4822A3887401C50DCB6AA56B44C06CD43EBA843ED339B'
    + '91991E791B956752EF773D5B359E988C7CA4AF92DAA14E046DFB3DE5220EC3884C786B8443574211A4970FA78');
  FCryptoPPVectorOutputs_SPECK128_CBC := TCryptoLibStringArray.Create
    ('88E166E1D46064E47187F9854A19570223E96BE0EE13D890E0209B66F0E45808F9B60513D90EAC2F0C1BF8A'
    + '55EF2B637B72597D9B9B3107FD42FD86AC9EE58D983C334F938FDC7E50DE292AC030FF3C68B6C5F5DA298DAB7438F322B8E4F003CE5310BC88074E98D9C38045D40C956909F766774CE00C30BBE2D7DDDDC94C96D9FA252EB5EB514'
    + 'D066D8DB995526F402389057C2310F64B26BF936C902D7B4F4E4E9D9DFB4294DFFB81BC3A524EFD7A80317E8F812E940137172F6DA27B4C01D',
    '73024FB7D9931CFC64738C1B46417089226FA3E1ACAC0FBDE253B8C46673AB61142C76CC8F965762113384C462793FC01F7B8FE04EB42D9276E25F7C'
    + 'CB4DEAED845CCA1F14EE034628E917EC7B95D658E00B1DED8F2E0D44BEBEF62B5BBAD9E3872BB5600842991918F6DC8D8E2D96CEA85743270BC7DF4A0363E65959794910A3EB9689A8DF'
    + '5AB314A26B31B60AA63EFD57AD5FFBBAA793996B71841F468F99B485CB0CEEE6D10130BEB091A4D55206577A354768E5B8A044C6BE7C992EB0EF',
    '21BA4DF8F5BC068B530800358033A3B976098B304E8CCAA264F9BB3FB5E0BDB5C888E6BB9AC6508B8F56798DBACDCBFE963AB5172E4A4FC2FD160CFD378A597E6F1E8FE0'
    + 'DCEA6BA0B06142BA49FFDCF05F1E9D02D06E71B1FAD3E8A6E8B14C65AD24973B5739D076EBAD7E4ED9ECF9E360CA32E41066A5E669DF888F49803F55FD7097'
    + 'ED4D182552F71720E77A416046A81C71A53E3F6DD8FBEAB1D9F5F4146E4E2E4F0A344A740F8091135B1CF6C04B3B00B6E557F0F8078894483242DC165B');

  // ====================================================================================== //

  FCryptoPPVectorKeys_SPECK64_CTR := TCryptoLibStringArray.Create
    ('C72CBD543750780FBCD5CB64', 'D0F15E55870DD39236C0251C438F57B4');
  FCryptoPPVectorIVs_SPECK64_CTR := TCryptoLibStringArray.Create
    ('E4FE17997B0F8028', '6942E2B8C46D5374');
  FCryptoPPVectorInputs_SPECK64_CTR := TCryptoLibStringArray.Create
    ('2F75D63915E9E524D98DF7F6F5B32FFBE4B7F911F3CEC758FF265FB1B202C78A7F5353E508F23D84D6FFF2CA54AC649BF583A4098876A52EF54341F581AF8C2C2E5AF8734B7535B854295C0BB3A20B7382650F6262D33DC40403B79482A71437',
    'A71E62DCF454EEC5A1ED766C45B7B67AB82E5019AD8DB7F4AA0A53730AA301C11441908D4290643E71FF39E3666934A317912C68DF01E137E28A6047F7E12F5766D01E2016408AE554B63EA66DBF87AEBD1BCE95ADA845634E6D33D90E10E60E');
  FCryptoPPVectorOutputs_SPECK64_CTR := TCryptoLibStringArray.Create
    ('AB692394FB3A7B7D4A356673075C947E04EE4CA1DC025EAEF950FF24527DE9E72DC4B3BE5E0C82A7964A64AE9820451910F448026C43FA0886A095E2277D484E90CFB960AA43023C958863D8741333AB3CB25B2BC4778DCFEAFA89C9DC6285E6',
    '309D96C038FD03AA85815D6EF445344037980EACD6B61BCDD7F74FF8207F0F0533AF40AB822F480DB08C9729CF59BF2D3EF4192EBA1087BCBC112B46EA4D512AF2FA8FFCE2824C316D401771A25BF98E842BDA8120039AE2049733B329A189DA');

  // ====================================================================================== //

  FCryptoPPVectorKeys_SPECK128_CTR := TCryptoLibStringArray.Create
    ('B043F5B45E8256956AFC4E26B4861240',
    '691EC1C805EFBD7A9D509F226D2331D20771EE79BDDFCAFC',
    'EB78929D56C5D0F49F75C1C8694AFDA496F808E5524CC592FD980EEC363E5382');
  FCryptoPPVectorIVs_SPECK128_CTR := TCryptoLibStringArray.Create
    ('E0BEDD6ECE0D72FC19D59E7BF853AEEC', '348ECA9766C09F04826520DE47A212FA',
    'AF322427139F48ECD9C779FB768B28C0');
  FCryptoPPVectorInputs_SPECK128_CTR := TCryptoLibStringArray.Create
    ('4CB83714C34CA56DE8FB06069F794A5189F468191552CF8F5C46A07960BAC354C2D73359B01BF1508213ABF986ACA73E413566129134A6DAAAF54A45F7CFFE63E476B6EF237FA1FB0878F30338A18D29B91E204F37FC504A'
    + '4908103AE843CDB05FACE5CC5EBD85D603F187CC4245D18D78036B81F8980A86A333418D7F81C75214D30555368B5D11A56AE732B291003128181F8364EA2C3D1C333C7615EFF41078E9CC8C69BB87BCE5EB8630E9B2E261758DF6693730E3C5F5C8F4F9F992D886',
    '8BF93C7DFA63CF6D78842FD7458A6CB17184F75ECBE1DC0BE9F32DAC0E8F28D5152FE7351A46A402AE019C38BA55B2EF6C00DEAF4BF721A8C6C15434E466CBAEFA643BCCFEB4F2FAA5CE9178DB83DDE37A2F388ED9FFFB91DF4E2F16D84D9B03A122ACD1745FF2E3568C4F535689FEB99A30985EAD5BEF39A0'
    + '730B569326FB23435CCE3696A8CD42C6D8C57A04134ADE9A68D927A16890CBD245A2FDF4E194550692A75A196780140AEBA98E800BE9851EDE654D4AB8EE31FADB1815CB66BCA8',
    '5DCC0F8301F377741D8517CD6DA27D1E8170109C361FC68D8E5022CE3DA1C8FBDD37F50A7DCB5BB1A059D7CF100A94EAB59ECE9260072B64B746FD9ED93F49F0C654CD5DFD321E4D8959CBD1095FE2B5D4ACC78474AC2232EC34ECA0737F8886E156866C279C679CBAF544E7F69E3E8C710DE732C1F8FEEDF20773C6A'
    + '674D706BF7EF2B5AD9C3D7B00A734E0919F181B59FBC8CFCEA4BEE9525894814CE42122E3AD0F07C0AD56E899D780C5D1759312351057C15F550C965379BADFC728E8F3');
  FCryptoPPVectorOutputs_SPECK128_CTR := TCryptoLibStringArray.Create
    ('A17264CC79FB96348E22E42F8FA8DCB43E9415AEF3552A673D5BF27B81E810F15923578D0B5CA148B183FB51AEE2E23CE2CFE4820B91DF21A6C915B2268608A62960EE8802991546048BDB4C2B9461B55869335954EABBAF09F255FA'
    + 'E862140E87AABBF497AE3578AD030FBC4CB87A5EE4DEEB114FA4DE64DA74CE1AEA41D9FC72962B26C1339E2593166E8D79E06EAE809A080D4197934298FBE3586A3235CA76A176E41DE1A0BEF47CD37F5DE36E79C78E20A2E6BD0DCFE27A5A71431A5983',
    '8F1C06AD392094314A7C514FEE0BA31A4129325900789A5F0F5638F5114509F07C22C527B41831ECF67B25EDEB4A069481950B7BE611772129F7995011A1429CF26CB6E91E970D745958223DCB55D606A7D78C20F5866D532C7CE27A97D1DCBA43494948C969820117DA62B83F421270BC90997F0ABC27099AAA9610FF44C48'
    + 'BD701EB20DEA3008164097783E6006010AE26486D46726E0507E4C8F3F9448EC29642AD71A05B60A1386E39B81E747B64C8B39F73E27208B1EA3BC075223804AA',
    '46DDAF62B84BDB9B97E2C114417AA5BD126132D922FA7B2C8B25A0D3147C9C1B203F06C546A7DAE20E98BC95AC6CB124C0E7C51566B5D1061EE61E25405E51CD6EB848C673E21BC10F9B9DCC36DDC16281F1369D9DFAABDB43C50C7CE10BF9805596D8C3CA530810C1BE9EBDCC0950BDA5A0CEB196B8E81CD1678094'
    + '81E61E46B7748C8B88D7169352C41761C0536286A61619BBB841E19EA7867DE51DAAD87080C317A4B269AE8D5BD6087E61BF9EE765DC69619E87FBC1AB1E26EA9CF9EA42');

  // ====================================================================================== //

end;

end.
